/*
* Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* $Id: sessiontabwidget.cpp 599 2010-06-04 21:36:49Z jpnurmi $
*/

#include "sessiontabwidget.h"
#include "commandengine.h"
#include "application.h"
#include "messageview.h"
#include "settings.h"
#include "session.h"
#include <ircutil.h>
#include <irc.h>
#include <QtGui>

SessionTabWidget::SessionTabWidget(Session* session, QWidget* parent) :
    TabWidget(parent)
{
    QIcon icon(":/resources/oxygen/16x16/actions/bookmark.png");
    setAlertIcon(icon);
    setHighlightIcon(icon);

    connect(this, SIGNAL(currentChanged(int)), this, SLOT(tabActivated(int)));
    connect(session, SIGNAL(bufferAdded(Irc::Buffer*)), this, SLOT(bufferAdded(Irc::Buffer*)));
    connect(session, SIGNAL(bufferRemoved(Irc::Buffer*)), this, SLOT(bufferRemoved(Irc::Buffer*)));

    QShortcut* shortcut = new QShortcut(QKeySequence::Close, this);
    connect(shortcut, SIGNAL(activated()), this, SLOT(closeCurrentView()));

    d.tabLeftShortcut = new QShortcut(this);
    connect(d.tabLeftShortcut, SIGNAL(activated()), this, SLOT(moveToPrevTab()));

    d.tabRightShortcut = new QShortcut(this);
    connect(d.tabRightShortcut, SIGNAL(activated()), this, SLOT(moveToNextTab()));

    applySettings();

#if QT_VERSION >= 0x040600
    registerSwipeGestures(Qt::Horizontal);
#endif

    d.session = session;
    d.engine = new CommandEngine(this);
    d.engine->setScriptObject("app", qApp);
    d.engine->setScriptObject("window", window());
    d.engine->setScriptObject("session", session);
    d.engine->setScriptObject("tabWidget", this);
}

Session* SessionTabWidget::session() const
{
    return d.session;
}

QStringList SessionTabWidget::channels() const
{
    QStringList list;
    foreach (const QString& receiver, d.views.keys())
    {
        if (receiver.startsWith("#") || receiver.startsWith("&"))
            list << receiver;
    }
    return list;
}

void SessionTabWidget::openView(const QString& receiver)
{
    /*MessageView* view = 0;
    if ((view = handler.view(receiver)))
    {
        setCurrentWidget(view);
    }
    else
    {
        view = new MessageView(d.session->createBuffer(receiver), this);
        connect(view, SIGNAL(send(QString)), this, SLOT(send(QString)));
        connect(view, SIGNAL(query(QString)), this, SLOT(openView(QString)));
        connect(view, SIGNAL(command(QString)), sessio, SLOT(sendRaw(QString)));
        connect(view, SIGNAL(alert()), this, SLOT(tabAlert()));

        handler.addView(view);
        int index = addTab(view, receiver);
        setCurrentIndex(index);
    }*/
}

void SessionTabWidget::closeCurrentView(const QString& message)
{
    if (count() > 1)
    {
        int index = currentIndex();
        QString receiver = tabText(index);
        closeView(receiver, message);
    }
}

void SessionTabWidget::closeView(const QString& receiver, const QString& message)
{
    QString tmp = receiver;
    if (!tmp.startsWith('#') && !tmp.startsWith('&') && !d.views.contains(tmp.toLower()))
        tmp.prepend("#");

    if (tmp.startsWith('#') || tmp.startsWith('&'))
        d.session->part(tmp, message);

    MessageView* view = d.views.take(tmp.toLower());
    if (view)
    {
        if (indexOf(view) == 0)
        {
            // closing a server tab
            emit disconnectFrom(QString());
            deleteLater();
        }
        view->deleteLater();
    }
}

void SessionTabWidget::bufferAdded(Irc::Buffer* buffer)
{
    MessageView* view = new MessageView(buffer, this);
    connect(view, SIGNAL(send(QString, QString)), this, SLOT(send(QString, QString)));
    //connect(view, SIGNAL(query(QString)), this, SLOT(openView(QString)));
    connect(view, SIGNAL(rename(MessageView*)), this, SLOT(nameTab(MessageView*)));
    connect(view, SIGNAL(alert(MessageView*)), this, SLOT(alertTab(MessageView*)));
    connect(view, SIGNAL(highlight(MessageView*)), this, SLOT(highlightTab(MessageView*)));

    d.views.insert(buffer->receiver().toLower(), view);
    int index = addTab(view, buffer->receiver());
    setCurrentIndex(index);
}

void SessionTabWidget::bufferRemoved(Irc::Buffer* buffer)
{
    MessageView* view = d.views.take(buffer->receiver().toLower());
    if (view)
        view->deleteLater();
}

void SessionTabWidget::send(const QString& receiver, const QString& message)
{
    if (message.trimmed().isEmpty())
        return;

    if (message.startsWith('/'))
    {
        d.engine->setScriptObject("view", d.views.value(receiver.toLower()));
        if (!d.engine->evaluateCommand(message.mid(1), receiver, d.views.keys()))
        {
            // failed
            qDebug("failed to evaluate: %s", qPrintable(message));
        }
    }
    else
    {
        d.session->message(receiver, message);
    }
}

void SessionTabWidget::tabActivated(int index)
{
    MessageView* view = static_cast<MessageView*>(currentWidget());
    if (view)
    {
        d.engine->setScriptObject("messageView", view);
        d.session->setDefaultBuffer(view->buffer());
    }

    setTabAlert(index, false);
    setTabHighlight(index, false);
    if (isVisible())
    {
        window()->setWindowFilePath(tabText(index));
        if (view)
            view->setFocus();
    }
}

void SessionTabWidget::delayedTabReset()
{
    d.delayedIndexes += currentIndex();
    QTimer::singleShot(500, this, SLOT(delayedTabResetTimeout()));
    if (isVisible())
        window()->setWindowFilePath(tabText(currentIndex()));
}

void SessionTabWidget::delayedTabResetTimeout()
{
    if (d.delayedIndexes.isEmpty())
        return;

    int index = d.delayedIndexes.takeFirst();
    tabActivated(index);
}

void SessionTabWidget::nameTab(MessageView* view)
{
    int index = indexOf(view);
    if (index != -1)
    {
        setTabText(index, view->buffer()->receiver());
        if (index == 0)
            emit titleChanged(view->buffer()->receiver());
    }
}

void SessionTabWidget::alertTab(MessageView* view)
{
    int index = indexOf(view);
    if (index != -1)
    {
        if (!isVisible() || index != currentIndex())
            setTabAlert(index, true);
    }
}

void SessionTabWidget::highlightTab(MessageView* view)
{
    int index = indexOf(view);
    if (index != -1)
    {
        if (!isVisible() || index != currentIndex())
            setTabHighlight(index, true);
    }
}

void SessionTabWidget::applySettings()
{
    Settings settings = Application::settings();
    d.tabLeftShortcut->setKey(QKeySequence(settings.shortcuts.value(Settings::TabLeft)));
    d.tabRightShortcut->setKey(QKeySequence(settings.shortcuts.value(Settings::TabRight)));
}
